package com.xmy.cultivate.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xmy.cultivate.entity.FileDowload;
import com.xmy.cultivate.mapper.FileDowloadMapper;
import com.xmy.cultivate.service.FileDowloadService;
import com.xmy.cultivate.util.Code;
import com.xmy.cultivate.util.IdWorker;
import com.xmy.cultivate.util.Result;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/api/FileDownload")
@Scope("prototype")
public class FileDownloadController {
    private static final String DOWNLOAD_DIR = "D:\\Cache\\";

    private static int statu = 0;

    @Autowired
    private FileDowloadService fileDowloadService;

    @Autowired
    FileDowloadMapper fileDowloadMapper;

    @Autowired
    IdWorker idWorker;

    @RequestMapping(value = "/download", method = RequestMethod.GET)
    @ResponseBody
    public void download(HttpServletResponse response,@RequestParam("fileName") String FileName) throws IOException {
        File file = new File("D:\\Cache\\" + FileName);
        FileInputStream fis = new FileInputStream(file);
        response.setHeader("Content-Disposition", "attachment; filename=" + file.getName());
        response.setContentType("application/octet-stream");
        IOUtils.copy(fis, response.getOutputStream());
        response.flushBuffer();
    }
    @RequestMapping(value = "/fileInquire", method = RequestMethod.GET)
    @ResponseBody
    public Result fileInquire(@RequestParam("resumableIdentifier") String resumableIdentifier) {
        List<Integer> nowSection = fileDowloadMapper.selectSectionByMd5(resumableIdentifier);
        return new Result(Code.OK,nowSection,"");
    }



    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    @ResponseBody
    public Result upload(@RequestParam("file") MultipartFile file,
                         @RequestParam("fileName") String fileName,
                         @RequestParam("partNumber") int partNumber,
                         @RequestParam("totalParts") int totalParts,
                         @RequestParam("resumableIdentifier") String resumableIdentifier) {
        try {
            String tempDir = "D:\\Cache\\";
            QueryWrapper queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("file_name",fileName);
            queryWrapper.eq("part_number",partNumber);
            FileDowload fileDowload = fileDowloadMapper.selectOne(queryWrapper);
            List<Integer> nowSection = fileDowloadMapper.selectSection(fileName);
            if(nowSection.size() == totalParts){
                return new Result(Code.ERROR,0,"当前文件已经存在");
            }
            if(fileDowload != null && fileDowload.getFileName() != null){
                    return new Result(Code.ERROR,0,"当前切片已经存在");
            }else{
                fileDowload = new FileDowload();
                fileDowload.setId(String.valueOf(idWorker.nextId()));
                fileDowload.setFileName(fileName);
                fileDowload.setSaveDir(tempDir);
                fileDowload.setMd5(resumableIdentifier);
                fileDowload.setPartNumber(partNumber);
                fileDowload.setTotalParts(totalParts);
                fileDowloadMapper.insert(fileDowload);
            }
            File tempFile = new File(tempDir, resumableIdentifier + ".part" + partNumber);
            file.transferTo(tempFile);
            List<Integer> section = fileDowloadMapper.selectSection(fileName);
            // 如果所有部分都上传完成，就开始合并文件
            if (section.size() == totalParts) {
                String saveDir = "D:\\Cache\\";
                File saveFile = new File(saveDir, fileName);
                RandomAccessFile raf = new RandomAccessFile(saveFile, "rw");
                for (int i = 1; i <= totalParts; i++) {
                    File partFile = new File(tempDir, resumableIdentifier + ".part" + i);
                    byte[] buffer = new byte[1024];
                    int len;
                    try (InputStream in = new FileInputStream(partFile)) {
                        while ((len = in.read(buffer)) != -1) {
                            raf.write(buffer, 0, len);
                        }
                    }
                    if (partFile.delete()) {// 删除已经合并的部分文件
                        //System.out.println(partFile + "删除成功");
                    }else{
                        //System.out.println(partFile + "删除失败");
                    }
                }
                raf.close();
                RecycleBin();
                //ClearRecycleBin();
                return new Result(Code.OK,1,"文件下载完成");
            }
        } catch (IOException e) {
            e.printStackTrace();
            return new Result(Code.ERROR,0,"文件下载异常");
        }
        List<Integer> section = fileDowloadMapper.selectSection(fileName);
        return new Result(Code.ERROR,section,"当前切片下载完整");
    }

    @RequestMapping(value = "/fileDelete", method = RequestMethod.GET)
    @ResponseBody
    public Result fileDelete(@RequestParam("resumableIdentifier") String resumableIdentifier) {
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("md5",resumableIdentifier);
        List<FileDowload> fileDowloadList = fileDowloadMapper.selectList(queryWrapper);

        String folderPath = "D:\\Cache\\"; // 文件夹路径
        for(FileDowload fileDowload : fileDowloadList){
            File tempFile = new File(folderPath, resumableIdentifier + ".part" + fileDowload.getPartNumber());
            if (tempFile.delete()) {
                //System.out.println(tempFile + "删除成功");
            } else {
                //System.out.println(tempFile + "删除失败");
            }
        }
        fileDowloadMapper.delete(queryWrapper);
        RecycleBin();
        //ClearRecycleBin();
        return new Result(Code.ERROR,null,"中断下载成功，文件已删除~");
    }

    @RequestMapping(value = "/resumeUpload", method = RequestMethod.POST)
    @ResponseBody
    public String resumeUpload(@RequestParam("file") MultipartFile file,
                               @RequestParam("partNumber") int partNumber,
                               @RequestParam("totalParts") int totalParts,
                               @RequestParam("resumableIdentifier") String resumableIdentifier) throws IOException {
        String filename = file.getOriginalFilename() + "_" + resumableIdentifier + "_" + partNumber + "_" + totalParts;
        //System.out.println(filename);
        File localFile = new File("D:\\Cache\\" + filename);
        file.transferTo(localFile);
        return "上传成功";
    }

    public void RecycleBin(){
            // 回收站路径
            String recycleBinPath = "C:\\$Recycle.Bin\\";
            // 创建文件对象
            File recycleBin = new File(recycleBinPath);
            // 判断回收站是否存在
            if (recycleBin.exists()) {
                // 获取回收站中的所有文件和文件夹
                File[] files = recycleBin.listFiles();
                // 遍历回收站中的所有文件和文件夹
                for (File file : files) {
                    // 删除文件或文件夹
                    if (file.isFile()) {
                        file.delete();
                    } else {
                        deleteDirectory(file);
                    }
                }
            } else {
                //System.out.println("回收站不存在！");
            }
        }
        // 删除文件夹
    public static void deleteDirectory(File directory) {
        if (directory.isDirectory()) {
            File[] files = directory.listFiles();
            for (File file : files) {
                if (file.isFile()) {
                    file.delete();
                    //System.out.println("delete" + file.getName() + "file success");
                } else {
                    deleteDirectory(file);
                    //System.out.println("delete directory success");
                }
            }
            directory.delete();
        } else {
            directory.delete();
        }
    }
    public void ClearRecycleBin() {
            String command = "rm -rf ~/.local/share/Trash/*";
            try {
                Runtime.getRuntime().exec(command);
                //System.out.println("Recycle bin has been cleared.");
            } catch (IOException e) {
                e.printStackTrace();
            }
    }
}